/***************************************************************
*  Copyright (c) 2007 by GroupMe! Team (www.groupme.net)
*  All rights reserved.
*
*  This file is part of the GroupMe! Project. Source code of 
*  this project is closed and redistribution of this code is
*  prohibited. 
*  
*  Contact: http://www.groupme.net
*
*  This copyright notice MUST APPEAR in all copies of the file!
***************************************************************/
package net.groupme.controller;

import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.groupme.controller.model.HtmlFormattedElement;
import net.groupme.group.GroupManager;
import net.groupme.gui.constants.VIEW_VOCABULARY;
import net.groupme.gui.rendering.TagRenderer;
import net.groupme.model.Group;
import net.groupme.model.ObjectFactory;
import net.groupme.search.SEARCH_CONFIGURATION;
import net.groupme.search.SearchManager;
import net.groupme.search.strategy.model.WeightedTag;
import net.groupme.utils.ResourceTools;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

/**
 * created on Jun 16, 2008
 * 
 * This class/interface...
 * 
 * @author Fabian Abel, <a href="mailto:abel@l3s.de">abel@l3s.de</a>
 * @author last edited by: $Author: fabian $
 * 
 * @version $Revision: 1.3 $ $Date: 2008-11-17 15:43:45 $
 */
public class GroupVisualizingController implements Controller, ApplicationContextAware{

	/** Logger for this class and subclasses */
	protected final Log logger = LogFactory.getLog(getClass());
	
	
	/** the application context */
	ApplicationContext applicationContext = null;

	/**
	 * Set the ApplicationContext that this object runs in. 
	 * @param applicationContext the current {@link ApplicationContext} 
	 */
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		this.applicationContext = applicationContext;
	}
	
	/** ID of view for testing different group visualizations */
	public static final String TEST_VISUALIZING_VIEW = "test-visualizer";
	
	/** URI Pattern of view for testing different group visualizations */
	public static final String TEST_VISUALIZING_URI_PATTERN = "visualize-group";
	
	/** Parameter name of the variable, which contains the ID of the visualizer */
	public static final String PARAMETER_VISUALIZER = "visualizer";
	
	/* (non-Javadoc)
	 * @see org.springframework.web.servlet.mvc.Controller#handleRequest(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
	 */
	public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
		String userRequest = request.getRequestURI();
    	userRequest = userRequest.substring(userRequest.lastIndexOf("/") + 1);
    	
		logger.info("Requested Site/Action: " + userRequest );
		
    	//create the MaV:
    	ModelAndView mav = new ModelAndView();
    	mav = browseGroups(request, response);
    	mav.setViewName(TEST_VISUALIZING_VIEW);
		return mav;
	}
	
	
	/**
	 * 
	 * 
	 * @param request the HTTP request
	 * @param response the HTTP response
	 * 
	 * @return the Spring {@link ModelAndView} object which includes the indicator for the <i>group view</i>
	 */
	private ModelAndView browseGroups(HttpServletRequest request, HttpServletResponse response){
		String id = getStringValue(request, VIEW_VOCABULARY.PARAMETER_ID);
		if (id == null){
			id="default";
		}
		ModelAndView mav = new ModelAndView();
		
//		Does the given group exist?
		if(!ResourceTools.doesResourceWithGivenIdExists(id, true) && id != "default"){
			mav.setViewName(VIEW_VOCABULARY.VIEW_GENERAL_ERROR);
			return mav;
		}
		mav.addObject(VIEW_VOCABULARY.PARAMETER_ID, id);
		mav.setViewName(VIEW_VOCABULARY.VIEW_BROWSE_GROUPS);
		
		//SUCHMASCHINEN-FREUNDLICHKEIT:
		//Tags + TagCloud der Gruppe berechnen:
		GroupManager gm = (GroupManager) applicationContext.getBean(VIEW_VOCABULARY.GROUP_MANGER, GroupManager.class);
		if(id != "default"){
			gm.setGroup(ObjectFactory.getGroup(id));
		}
		Group group = gm.getGroup();
		if(group != null){
			logger.info("Starting to compute tag cloud for: " + group.getName());
			SearchManager searchManager =(SearchManager) applicationContext.getBean(VIEW_VOCABULARY.GROUPME_SEARCH_MANGER, SearchManager.class);
			List<WeightedTag> weightedTags = searchManager.computeTagCloud(group, SEARCH_CONFIGURATION.TAG_CLOUD_MIDDLE_MAX_NUMBER_OF_TAGS);
			
			//Tags der Gruppe:
			mav.addObject("taglistAsString", getTagsFromTagCloud(weightedTags));
			HtmlFormattedElement tagCloud = new HtmlFormattedElement(null, new TagRenderer().renderTagCloud(weightedTags));
			
			//TagCloud der Gruppe:
			mav.addObject("tagcloud", tagCloud);
			
			//Description
			mav.addObject("descriptionString", gm.getGroup().getDescription());
			
			
			//Name der Gruppe
			mav.addObject("nameOfGroup", getNameOfGroup(gm.getGroup().getName()));
			
		}
		return mav;
	}

	
	//method which returns a string with the tags of a group generated by the tag cloud
	private String getTagsFromTagCloud(List<WeightedTag> weightedTags){
		String tags = "";
		for(WeightedTag wt: weightedTags){
			tags += wt.tag.getKeyword() + ", ";
		}
		return tags;
	}
	
	//proofs if the name of a group is not empty; 
	//used to display a headline in every case(even if the groupname is empty or no group is selected in the group-browsing view
	private String getNameOfGroup(String nameOfGroup){
		if (nameOfGroup == "" || nameOfGroup == null){
			return "Explore the GroupMe! Groups";
		}
		return nameOfGroup;
	}
	
    
	/**
     * Very small helper function to extract a given parameter or attribute from a HttpServletRequest.
     * @param request the {@link HttpServletRequest} object
     * @param parameter the parameter
     * @return the value of the parameter as a String
     */
    private String getStringValue(HttpServletRequest request, String parameter){
    	String value = request.getParameter(parameter);
    	if(value == null && request.getAttribute(parameter) != null){ //normally this is not accessed but we do our best to extract the value.. 
    		value = request.getAttribute(parameter).toString();
    	}
    	return value;
    }
    

}
